<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
	<title>Using forms</title>
  <link rel="stylesheet" type="text/css" href="documentation.css" />
</head>
<body>
<h1>Using forms</h1>
<h2>Form behaviour</h2>
<p>A very common pattern of web applications, is to write HTML forms. Konstrukt provides a standard mechanism for making it simple and fast to whip up a form, with the <code>k_FormBehaviour</code> component. As with all abstractions, this particular component restrict your freedom as a developer a bit. There may be situations, where the standard form behaviour doesn&#039;t really fit your needs. In these cases, you shouldn&#039;t try to shoehorn your application into the framework. That said, k_FormBehaviour is highly configurable, and can be extended in different directions.</p>
<p>Taking a step back, forms are essentially just controllers which displays the HTML markup for a <code>&lt;form&gt;</code> on a GET-request, and process the contents on a POST request. Further, most forms will do some filtering on input, and some sort of validation, before processing. Since validation may fail, forms should have the ability to re-populate and re-display, displaying validation errors. To prevent the dreaded &#039;broken-back-button&#039; problem, most forms are programmed to re-direct to itself, following a POST request (Also known as the <a href="http://www.theserverside.com/tt/articles/article.tss?l=RedirectAfterPost">PRG-pattern</a>. All of these features are implemented in <code>k_FormBehaviour</code>.</p>
<h2>Creating a form</h2>
<p>To promote code reuse and decoupling, <code>k_FormBehvaiour</code> is implemented as a component, rather than an abstract controller. This means that you use it in your code through composition, rather then inheritance. The syntax is a bit more verbose, but offers greater flexibility.</p>
<p>Implementing a form, is a matter of instantiating a <code>k_FormBehaviour</code>, and delegating control to it. The following example shows how:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="kw2">function</span> __construct<span class="br0">&#40;</span>k_iContext <span class="re0">$context</span>, <span class="re0">$name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">parent</span>::__construct<span class="br0">&#40;</span><span class="re0">$context</span>, <span class="re0">$name</span><span class="br0">&#41;</span>;
    <span class="re0">$this</span>-&gt;<span class="me1">form</span> = <span class="kw2">new</span> k_FormBehaviour<span class="br0">&#40;</span><span class="re0">$this</span>, <span class="st0">&quot;templates/myform.tpl.php&quot;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
&nbsp;
  <span class="kw2">function</span> execute<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>This rudimentary example will create a form -- sort of -- but the form won&#039;t have any fields, and it isn&#039;t really useful for a couple of other reasons.</p>
<h2>Form descriptor</h2>
<p>Forms are meant to gather information from the user, and information is broken down into a number of fields. Each field is kept in a separate variable, and is presented in a distinct input control; Often represented by a single HTML element, such as an <code>&lt;input&gt;</code> tag. The form behaviour needs to know which fields the form contains. You provide this information by setting the <code>$descriptors</code> property. This is an array of field descriptors. Each descriptor is itself an associative array with certain configuration settings, of which &quot;name&quot; is the most important (And only one required).</p>
<p>Let&#039;s assume that we want to create a sign-up form for our web site. The form should contain an email address and a password field. This is how the descriptor could look like:</p>
<pre class="php"><span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">descriptors</span> = <span class="kw3">Array</span><span class="br0">&#40;</span>
  <span class="kw3">Array</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span> =&gt; <span class="st0">&quot;email&quot;</span><span class="br0">&#41;</span>,
  <span class="kw3">Array</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span> =&gt; <span class="st0">&quot;password&quot;</span><span class="br0">&#41;</span>,
<span class="br0">&#41;</span>;</pre><h3>Default values</h3>
<p>As mentioned, &quot;name&quot; isn&#039;t the only value that a field descriptor can have. Sometimes you want to pre-populate fields with reasonable starting values. In this example, let&#039;s assume that the form will contain another field &quot;country&quot;, which is supposed to be used to tell which country the user is from. Most of our users are from Uzbekistan, so it&#039;s a reasonable value to default to. We can add a default value this way:</p>
<pre class="php"><span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">descriptors</span> = <span class="kw3">Array</span><span class="br0">&#40;</span>
...
  <span class="kw3">Array</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span> =&gt; <span class="st0">&quot;country&quot;</span>, <span class="st0">&quot;default&quot;</span> =&gt; <span class="st0">&quot;Uzbekistan&quot;</span><span class="br0">&#41;</span>,
<span class="br0">&#41;</span>;</pre><div class="note">Note: Providing default values like this, is convenient for constants. Sometimes you need to calculate the values at runtime. For this, you can implement <code>getDefaultValues()</code> on the controller. The form behaviour will see this and call back and use that data instead.</div>
<h3>Filters</h3>
<p>Another option of the field descriptor, is the ability to supply one or more filters for the input data. For example, if you wanted the email to be all lowercase:</p>
<pre class="php"><span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">descriptors</span> = <span class="kw3">Array</span><span class="br0">&#40;</span>
  <span class="kw3">Array</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span> =&gt; <span class="st0">&quot;email&quot;</span>, <span class="st0">&quot;filters&quot;</span> =&gt; <span class="kw3">Array</span><span class="br0">&#40;</span><span class="st0">&quot;strtolower&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,
...
<span class="br0">&#41;</span>;</pre><p>A common trick, is to add <code>trim()</code> as a filter, to prevent users from acidentially typing a leading or trailing white space.</p>
<h2>Template</h2>
<p>The next thing we need to do, is to provide a template. As you can see in the example above, we have told the form to use the file <code>templates/myform.tpl.php</code> as a template. For starters, let&#039;s use the following:</p>
<pre>&lt;form <span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$this</span>-&gt;<span class="me1">getFormProperties</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span>&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">fields</span> <span class="kw1">as</span> <span class="re0">$field</span><span class="br0">&#41;</span> : <span class="kw2">?&gt;</span>
&lt;p&gt;
&lt;label for=&quot;<span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$field</span>-&gt;<span class="me1">id</span>; <span class="kw2">?&gt;</span>&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$field</span>-&gt;<span class="me1">name</span>; <span class="kw2">?&gt;</span>&lt;/label&gt;
<span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$field</span>; <span class="kw2">?&gt;</span>
<span class="kw2">&lt;?php</span> <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$field</span>-&gt;<span class="me1">messages</span> <span class="kw1">as</span> <span class="re0">$error</span><span class="br0">&#41;</span> : <span class="kw2">?&gt;</span>
&lt;span&gt;<span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$error</span>; <span class="kw2">?&gt;</span>&lt;/span&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endforeach</span>; <span class="kw2">?&gt;</span>

&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endforeach</span>; <span class="kw2">?&gt;</span>

&lt;input type=&quot;submit&quot; /&gt;
&lt;/form&gt;</pre>
<p>This is basically some HTML, with a little bit of embedded PHP. While this will get us a basic form, there are a few tricks, you can pull to beef up the template a bit. Let&#039;s go through the possibilities:</p>
<p><code>$this</code> refers to the rendering component -- in this case, the <code>k_FormBehaviour</code> object. The most important property here, is <code>$this-&gt;fields</code>. This property is traversable, which means that it can be looped over with <code>foreach</code> as in this example, but sometimes you need to present specific fields differently. You can get a specific property by its name, using <code>$this-&gt;fields-&gt;foo</code>, where &quot;foo&quot; is the name of the field. In cases where you refer a single field explicitly in this way, you will still want to be able to loop over the remaining fields. You can use <code>getExclusive()</code> to get all fields, except the ones explicitly named. <code>getExclusive()</code> takes variable number of arguments, so to get all fields, except &quot;foo&quot; and &quot;bar&quot;, you could use:</p>
<pre><span class="kw2">&lt;?php</span> <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">fields</span>-&gt;<span class="me1">getExclusive</span><span class="br0">&#40;</span><span class="st0">&quot;foo&quot;</span>, <span class="st0">&quot;bar&quot;</span><span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$field</span><span class="br0">&#41;</span> : <span class="kw2">?&gt;</span></pre>
<p>If you prefer, you can also call it with one argument, which is an array of names. It depends on the situation, which method is the most practical.</p>
<p>The object returned by these methods, is an instance of <code>k_Field</code>.</p>
<h3>Customising form rendering</h3>
<p>The field belongs to <code>$this-&gt;fields</code>, which is a <code>k_FieldCollection</code>. In the above example, we have simply been echo&#039;ing the field. This implicitly calls the fields <code>render()</code> method. This calls back to the form behaviour. If the hosting component implements <code>renderField()</code>, rendering is delegated to this; Otherwise, a default <code>&lt;input type=text /&gt;</code> is returned. This pipeline allows you to reuse the same form template, in forms shich differs only in which fields, and which input-widget is used to edit it.</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="kw2">function</span> renderField<span class="br0">&#40;</span><span class="re0">$field</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">switch</span> <span class="br0">&#40;</span><span class="re0">$field</span>-&gt;<span class="me1">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw1">case</span> <span class="st0">'pass'</span>:
        <span class="kw1">return</span> <span class="st0">&quot;&lt;input type='password' name='pass' /&gt;&quot;</span>;
      <span class="kw1">case</span> <span class="st0">'image'</span>:
        <span class="kw1">return</span> <span class="st0">&quot;&lt;input type='file' name='image' /&gt;&quot;</span>;
      <span class="kw2">default</span>:
        <span class="kw1">return</span> <span class="st0">&quot;&lt;input type='text' name='&quot;</span>.<span class="re0">$field</span>-&gt;<span class="me1">name</span>.<span class="st0">&quot;' value='&quot;</span>.<span class="kw3">htmlspecialchars</span><span class="br0">&#40;</span><span class="re0">$field</span>-&gt;<span class="me1">value</span><span class="br0">&#41;</span>.<span class="st0">&quot;' /&gt;&quot;</span>;
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>You may find it practical to create a collection of helper function for generating standard widgets in <code>renderField()</code>.</p>
<h2>Required methods</h2>
<p>Now, as we have the rendering of the HTML representation of our form in place, let&#039;s take a look at the logic within. <code>k_FormBehaviour</code> expects that the context controller (<code>MyForm</code>) implements a method <code>validate()</code>, which will be invoked when the form is being submitted. If no such method is implemented, the form will generate a runtime error, when it&#039;s posted (submitted). To begin with, let&#039;s provide a dummy implementation of <code>validate()</code>:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
...
  <span class="kw2">function</span> validate<span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="kw2">TRUE</span>;
  <span class="br0">&#125;</span></pre><p>By returning <code>TRUE</code>, our form will pass, when submitted. For most forms, you&#039;d want to do some validation before that, but for now, we&#039;ll just let it get through.</p>
<p>Once the validation pass, we will run into the next problem. When a form is valid -- that is, when the form is submitted, and validation passes -- a method <code>validHandler()</code> will be called on the context. Just like with <code>validate()</code>, we need to provide this in our controller:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
...
  <span class="kw2">function</span> validHandler<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="st0">&quot;validHandler called&quot;</span>;
  <span class="br0">&#125;</span></pre><p>You can now submit the form, and the text &quot;validHandler called&quot; should appear.</p>
<h2>Validation</h2>
<p>So far, the validation is very forgiving, to say the least; In fact, it will always pass. To apply some real validation, we will have to implement the <code>validate()</code> method. In the simplest form, it returns <code>TRUE</code> if the form is valid, and <code>FALSE</code> if it isn&#039;t. To determine if the form is valid, the form field values are passed as an associative array to the method.</p>
<p>So a primitive validation could look like:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
...
  <span class="kw2">function</span> validate<span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="kw3">strlen</span><span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#91;</span><span class="st0">'password'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &gt;= <span class="nu0">8</span>;
  <span class="br0">&#125;</span></pre><p>This will ensure that the <em>password</em> field is at least 8 characters in length.</p>
<p>This is fine, but when the form <em>doesn&#039;t</em> validate, we would want to provide some feedback to the user as to what is wrong. To do this, we will use a convenient helper, provided by the <code>k_FormBehaviour</code> class. Calling the forms <code>getValidator()</code> method returns an instance of <code>k_Validator</code>. This object has a number of useful methods for validating the form.</p>
<p><code>failField()</code> logs a message on a field, and sets the state to failed. To log a failed validation on a specific field:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
...
  <span class="kw2">function</span> validate<span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$validator</span> = <span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">getValidator</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">strlen</span><span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#91;</span><span class="st0">'password'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &gt;= <span class="nu0">8</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw1">return</span> <span class="kw2">TRUE</span>;
    <span class="br0">&#125;</span>
    <span class="re0">$validator</span>-&gt;<span class="me1">failField</span><span class="br0">&#40;</span><span class="st0">'password'</span>, <span class="st0">'the password must be at least 8 characters in length'</span><span class="br0">&#41;</span>;
    <span class="kw1">return</span> <span class="kw2">FALSE</span>;
  <span class="br0">&#125;</span></pre><p>Alternatively, the method <code>fail()</code> logs a message on no specific field. Unlike its cousin, <code>failField()</code>, it takes just one argument.</p>
<p>Since certain primitive validations are often repeated over again, the validator has a couple of common assertions (Methods, that validate a field). These makes it easy to add simple validation to your form:</p>
<pre class="php"><span class="kw2">class</span> MyForm <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
...
  <span class="kw2">function</span> validate<span class="br0">&#40;</span><span class="re0">$values</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$validator</span> = <span class="re0">$this</span>-&gt;<span class="me1">form</span>-&gt;<span class="me1">getValidator</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
    <span class="re0">$validator</span>-&gt;<span class="me1">assertEmail</span><span class="br0">&#40;</span><span class="st0">'email'</span><span class="br0">&#41;</span>;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$validator</span>-&gt;<span class="me1">assertRequired</span><span class="br0">&#40;</span><span class="st0">'password'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="re0">$validator</span>-&gt;<span class="me1">assertEqual</span><span class="br0">&#40;</span><span class="st0">'password'</span>, <span class="st0">'password_repeat'</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
    <span class="kw1">return</span> <span class="re0">$validator</span>-&gt;<span class="me1">isValid</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span></pre><p>Each assertion returns the result, so you can make further validation on a field depend on previous validations. This can be observed in the example above, with the <em>password</em> field. The validator has an internal state. If an assertion fails, the state is <code>FALSE</code>. Thus you can call the assertions needed, and return the validators state at the end.</p>
<h2>Fine tuning</h2>
<p>In the above template, the opening HTML <code>&lt;form&gt;</code> tag is printed like:</p>
<pre class="php">&lt;form <span class="kw2">&lt;?php</span> <span class="kw3">echo</span> <span class="re0">$this</span>-&gt;<span class="me1">getFormProperties</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; ?&gt;&gt;</pre><p>The method <code>getFormProperties()</code> returns the attributes for the form tag. If you want to control these from the controller, you can set them through the <code>$properties</code> array. In particular, you would want to change the <code>enctype</code> key to <code>multipart/form-data</code>, if your form contains a file-upload control. Otherwise, the defaults are probably best left be.</p>
<p>After a forms <code>validHandler()</code> has been called, the memory will normally be wiped clean. If for some reason, you want the form to retain its values, even after it has been processed, you can set the property <code>$autoDestroy</code> to <code>FALSE</code>. One situation where you could use this, is in multipage forms (Sometime called wizards).</p>
</body>
</html>